programming4us
           
 
 
Programming

iPhone 3D Programming : Vertices and Touch Points - Boosting Performance with Vertex Buffer Objects

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
11/23/2010 11:43:39 AM
OpenGL provides a mechanism called vertex buffer objects (often known as VBOs) whereby you give it ownership of a set of vertices (and/or indices), allowing you to free up CPU memory and avoid frequent CPU-to-GPU transfers. Using VBOs is such a highly recommended practice that I considered using them even in the HelloArrow sample. Going forward, all sample code in this book will use VBOs.

Let’s walk through the steps required to add VBOs to Touch Cone. First, remove these two lines from the RenderingEngine class declaration:

vector<Vertex> m_coneVertices;
vector<GLubyte> m_coneIndices;

They’re no longer needed because the vertex data will be stored in OpenGL memory. You do, however, need to store the handles to the vertex buffer objects. Object handles in OpenGL are of type GLuint. So, add these two lines to the class declaration:

GLuint m_vertexBuffer;
GLuint m_indexBuffer;

The vertex generation code in the Initialize method stays the same except that you should use a temporary variable rather than a class member for storing the vertex list. Specifically, replace this snippet:

m_coneVertices.resize(vertexCount);
vector<Vertex>::iterator vertex = m_coneVertices.begin();

// Cone's body
for (float theta = 0; vertex != m_coneVertices.end() - 1; theta += dtheta) {

...

m_coneIndices.resize(m_bodyIndexCount + m_diskIndexCount);
vector<GLubyte>::iterator index = m_coneIndices.begin();



with this:

vector<Vertex> coneVertices(vertexCount);
vector<Vertex>::iterator vertex = coneVertices.begin();

// Cone's body
for (float theta = 0; vertex != coneVertices.end() - 1; theta += dtheta) {

...

vector<GLubyte> coneIndices(m_bodyIndexCount + m_diskIndexCount);
vector<GLubyte>::iterator index = coneIndices.begin();

Next you need to create the vertex buffer objects and populate them. This is done with some OpenGL function calls that follow the same Gen/Bind pattern that you’re already using for framebuffer objects. The Gen/Bind calls for VBOs are shown here (don’t add these snippets to the class just yet):

void glGenBuffers(GLsizei count, GLuint* handles);
void glBindBuffer(GLenum target, GLuint handle);

glGenBuffers generates a list of nonzero handles. count specifies the desired number of handles; handles points to a preallocated list. In this book we often generate only one handle at a time, so be aware that the glGen* functions can also be used to efficiently generate several handles at once.

The glBindBuffer function attaches a VBO to one of two binding points specified with the target parameter. The legal values for target are GL_ELEMENT_ARRAY_BUFFER (used for indices) and GL_ARRAY_BUFFER (used for vertices).

Populating a VBO that’s already attached to one of the two binding points is accomplished with this function call:

void glBufferData(GLenum target, GLsizeiptr size, 
const GLvoid* data, GLenum usage);

target is the same as it is in glBindBuffer, size is the number of bytes in the VBO (GLsizeiptr is a typedef of int), data points to the source memory, and usage gives a hint to OpenGL about how you intend to use the VBO. The possible values for usage are as follows:


GL_STATIC_DRAW

This is what we’ll commonly use in this book; it tells OpenGL that the buffer never changes.


GL_DYNAMIC_DRAW

This tells OpenGL that the buffer will be periodically updated using glBufferSubData.


GL_STREAM_DRAW (ES 2.0 only)

This tells OpenGL that the buffer will be frequently updated (for example, once per frame) with glBufferSubData.

To modify the contents of an existing VBO, you can use glBufferSubData:

void glBufferSubData(GLenum target, GLintptr offset, 
GLsizeiptr size, const GLvoid* data);

The only difference between this and glBufferData is the offset parameter, which specifies a number of bytes from the start of the VBO. Note that glBufferSubDataglBufferData. should be used only to update a VBO that has previously been initialized with

We won’t be using glBufferSubData in any of the samples in this book. Frequent updates with glBufferSubData should be avoided for best performance, but in many scenarios it can be very useful.

Getting back to Touch Cone, let’s add code to create and populate the VBOs near the end of the Initialize method:

// Create the VBO for the vertices.
glGenBuffers(1, &m_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glBufferData(GL_ARRAY_BUFFER,
coneVertices.size() * sizeof(coneVertices[0]),
&coneVertices[0],
GL_STATIC_DRAW);

// Create the VBO for the indices.
glGenBuffers(1, &m_indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
coneIndices.size() * sizeof(coneIndices[0]),
&coneIndices[0],
GL_STATIC_DRAW);

Before showing you how to use VBOs for rendering, let me refresh your memory on the gl*Pointer functions that you’ve been using in the Render method:

// ES 1.1
glVertexPointer(3, GL_FLOAT, stride, pCoords);
glColorPointer(4, GL_FLOAT, stride, pColors);

// ES 2.0
glVertexAttribPointer(positionSlot, 3, GL_FLOAT, GL_FALSE, stride, pCoords);
glVertexAttribPointer(colorSlot, 4, GL_FLOAT, GL_FALSE, stride, pColors);



The formal declarations for these functions look like this:

// From <OpenGLES/ES1/gl.h>
void glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
void glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
void glNormalPointer(GLenum type, GLsizei stride, const GLvoid* pointer);
void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
void glPointSizePointerOES(GLenum type, GLsizei stride, const GLvoid* pointer);

// From <OpenGLES/ES2/gl.h>
void glVertexAttribPointer(GLuint attributeIndex, GLint size, GLenum type,
GLboolean normalized, GLsizei stride,
const GLvoid* pointer);



The size parameter in all these functions controls the number of vector components per attribute. The stride parameter is the number of bytes between vertices. The pointer parameter is the one to watch out for—when no VBOs are bound (that is, the current VBO binding is zero), it’s a pointer to CPU memory; when a VBO is bound to GL_ARRAY_BUFFER, it changes meaning and becomes a byte offset rather than a pointer.

The gl*Pointer functions are used to set up vertex attributes, but recall that indices are submitted through the last argument of glDrawElements. Here’s the formal declaration of glDrawElements:

void glDrawElements(GLenum topology, GLsizei count, GLenum type, GLvoid* indices);


indices is another “chameleon” parameter. When a nonzero VBO is bound to GL_ELEMENT_ARRAY_BUFFER, it’s a byte offset; otherwise, it’s a pointer to CPU memory.


Note:

The shape-shifting aspect of gl*Pointer and glDrawElements is an indicator of how OpenGL has grown organically through the years; if the API were designed from scratch, perhaps these functions wouldn’t be so overloaded.


To see glDrawElements and gl*Pointer being used with VBOs in Touch Cone, check out the Render method in Example 1.

Example 1. RenderingEngine1::Render with vertex buffer objects
void RenderingEngine1::Render() const
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(m_rotationAngle, 0, 0, 1);
glScalef(m_scale, m_scale, m_scale);

const GLvoid* colorOffset = (GLvoid*) sizeof(vec3);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), 0);
glColorPointer(4, GL_FLOAT, sizeof(Vertex), colorOffset);
glEnableClientState(GL_VERTEX_ARRAY);

const GLvoid* bodyOffset = 0;
const GLvoid* diskOffset = (GLvoid*) m_bodyIndexCount;

glEnableClientState(GL_COLOR_ARRAY);
glDrawElements(GL_TRIANGLES, m_bodyIndexCount, GL_UNSIGNED_BYTE, bodyOffset);
glDisableClientState(GL_COLOR_ARRAY);
glColor4f(1, 1, 1, 1);
glDrawElements(GL_TRIANGLES, m_diskIndexCount, GL_UNSIGNED_BYTE, diskOffset);

glDisableClientState(GL_VERTEX_ARRAY);
glPopMatrix();
}


Example 2 shows the ES 2.0 variant. From 30,000 feet, it basically does the same thing, even though many of the actual OpenGL calls are different.

Example 2. RenderingEngine2::Render with vertex buffer objects
void RenderingEngine2::Render() const
{
GLuint positionSlot = glGetAttribLocation(m_simpleProgram, "Position");
GLuint colorSlot = glGetAttribLocation(m_simpleProgram, "SourceColor");

mat4 rotation = mat4::Rotate(m_rotationAngle);
mat4 scale = mat4::Scale(m_scale);
mat4 translation = mat4::Translate(0, 0, -7);
GLint modelviewUniform = glGetUniformLocation(m_simpleProgram, "Modelview");
mat4 modelviewMatrix = scale * rotation * translation;

GLsizei stride = sizeof(Vertex);
const GLvoid* colorOffset = (GLvoid*) sizeof(vec3);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUniformMatrix4fv(modelviewUniform, 1, 0, modelviewMatrix.Pointer());

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glVertexAttribPointer(positionSlot, 3, GL_FLOAT, GL_FALSE, stride, 0);
glVertexAttribPointer(colorSlot, 4, GL_FLOAT, GL_FALSE, stride, colorOffset);
glEnableVertexAttribArray(positionSlot);

const GLvoid* bodyOffset = 0;
const GLvoid* diskOffset = (GLvoid*) m_bodyIndexCount;

glEnableVertexAttribArray(colorSlot);
glDrawElements(GL_TRIANGLES, m_bodyIndexCount, GL_UNSIGNED_BYTE, bodyOffset);
glDisableVertexAttribArray(colorSlot);
glVertexAttrib4f(colorSlot, 1, 1, 1, 1);
glDrawElements(GL_TRIANGLES, m_diskIndexCount, GL_UNSIGNED_BYTE, diskOffset);

glDisableVertexAttribArray(positionSlot);
}


That wraps up the tutorial on VBOs; we’ve taken the Touch Cone sample as far as we can take it!

Other -----------------
- iPhone 3D Programming : Vertices and Touch Points - Saving Memory with Vertex Indexing
- iPhone 3D Programming : Vertices and Touch Points - Reading the Touchscreen
- iPhone 3D Programming : HelloCone with Shaders
- Search Engine Basics : Country-Specific Search Engines
- Search Engine Basics : Vertical Search Engines
- Building Android Apps : Animation - Adding the Settings Panel
- Building Android Apps : Animation - Adding the New Entry Panel
- Building Android Apps : Animation - Adding the Date Panel
- Building Android Apps : Animation - Adding the Dates Panel
- Building Android Apps : Animation - Sliding Home
- Programming Windows Azure : Understanding the Value of Queues
- Programming Windows Azure : Table Operations - Deleting Tables, Deleting Entities
- Programming Windows Azure : Table Operations - Updating Entities
- Programming Windows Azure : Table Operations - Understanding Pagination
- Programming Windows Azure : Table Operations - Using Partitioning
- Programming Windows Azure : Table Operations - Querying Data
- Programming Windows Azure : Table Operations - Creating Entities
- Programming Windows Azure : Table Operations - Creating Tables
- iPad Development : Document Management (part 2)
- iPad Development : Document Management (part 1)
 
 
 
Top 10
 
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
programming4us programming4us